import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {CookieService} from 'ngx-cookie-service';
import {Observable} from 'rxjs';

const AUTH_API = 'http://localhost:9000/uaa/realms/paragon/protocol/openid-connect';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  public clientId = 'frontend-client';
  public redirectUri = 'http://localhost:4200/';

  constructor(private httpClient: HttpClient,
              private cookieService: CookieService) { }

  public retrieveToken(code: string): void {
    const params = new URLSearchParams();
    params.append('grant_type', 'authorization_code');
    params.append('client_id', this.clientId);
    params.append('client_secret', 'frontendClientSecret');
    params.append('redirect_uri', this.redirectUri);
    params.append('code', code);

    const headers = new HttpHeaders({'Content-type': 'application/x-www-form-urlencoded; charset=utf-8'});

    this.httpClient.post(AUTH_API + '/token', params.toString(), { headers })
      .subscribe(
        response => this.saveToken(response),
        error => console.log(error)
      );
  }

  public refreshToken(): Observable<any> {
    console.log('Refreshing tokens');
    const params = new URLSearchParams();
    params.append('client_id', this.clientId);
    params.append('client_secret', 'frontendClientSecret');
    params.append('grant_type', 'refresh_token');
    params.append('refresh_token', this.cookieService.get('refresh_token'));

    const headers = new HttpHeaders({'Content-type': 'application/x-www-form-urlencoded; charset=utf-8'});

    return this.httpClient.post(AUTH_API + '/token', params.toString(), { headers });
  }

  public saveToken(token: any): void {
    const expireDate = new Date().getTime() + (1000 * token.expires_in);
    const refreshExpireDate = new Date().getTime() + (1000 * token.refresh_expires_in);

    this.cookieService.set('access_token', token.access_token, expireDate);
    this.cookieService.set('id_token', token.id_token, expireDate);
    this.cookieService.set('refresh_token', token.refresh_token, refreshExpireDate);

    console.log('Obtained tokens');
    console.log(token);
  }

  public getToken(): string {
    return this.cookieService.get('access_token');
  }

  public checkAccessToken(): boolean {
    return this.cookieService.check('access_token');
  }

  public checkRefreshToken(): boolean {
    return this.cookieService.check('refresh_token');
  }

  login(): void {
    window.location.href = AUTH_API + '/auth?response_type=code&&scope=openid%20write%20read&client_id=' +
      this.clientId +
      '&redirect_uri=' +
      this.redirectUri;
  }

  public logout(): void {
    const token = this.cookieService.get('id_token');
    this.cookieService.delete('access_token');
    this.cookieService.delete('id_token');
    this.cookieService.delete('refresh_token');
    window.location.href = AUTH_API + '/logout?id_token_hint' +
      token +
      '&post_logout_redirect_uri=' +
      this.redirectUri;
  }

}
